from dataclasses import astuple
from dataclasses import dataclass
from time import sleep
import re

from DrissionPage import Chromium
from DrissionPage.common import Settings

from fenbi_crawler.sqlite.DatabaseManager import DatabaseManager
from fenbi_crawler.sqlite.QuesTable import QuesTable

Settings.set_language('zh_cn')
chrom = Chromium()
TIME_WAITTING = 0.1
SKIP_ITEMS = ('政治理论', '常识判断', '资料分析', '数量关系')


@dataclass
class QuesInfo:
    paper_name: str = None
    ques_type: str = None
    content: str = None
    content_img: str = None
    choice_a: str = None
    choice_a_img: str = None
    choice_b: str = None
    choice_b_img: str = None
    choice_c: str = None
    choice_c_img: str = None
    choice_d: str = None
    choice_d_img: str = None
    answer: str = None
    rating: str = None


def login():
    url = 'https://www.fenbi.com/spa/tiku/guide/home/xingce/xingce'
    tab = chrom.latest_tab
    tab.listen.start()  # 开启监听器

    print('访问网页...')
    tab.get(url)
    tab.listen.wait_silent()  # 等到所有请求完成

    print('点击登录...')
    tab.ele('.header-content-logon-btn').click()
    tab.listen.wait_silent()

    phone = input('输入手机号：')
    tab.ele('.form-input ng-tns-c53-0 ng-untouched ng-pristine ng-invalid').input(phone)
    tab.ele('.verification-code-btn ng-tns-c53-0 ng-star-inserted active').click()
    verify = input('输入验证码：')
    tab.ele('.form-input-short ng-tns-c53-0 ng-untouched ng-pristine ng-invalid').input(verify)
    tab.ele('.agreement-action-btn ng-tns-c53-0').click()
    tab.ele('.form-item-btn ng-tns-c53-0').click()
    print('登录中...')


def analyse_papers():
    tab = chrom.latest_tab
    tab.listen.start()

    paging = tab.ele('@class=paging')
    start = int(paging.child(2).text.strip())
    end = int(paging.child(-2).text.strip())
    print(f'开始页码 {start}，结束页码 {end}')

    for page_index in range(start, end + 1):
        items_len = len(tab.eles('@tag()=app-paper-item'))
        for i in range(items_len):
            item = tab.ele('@tag()=app-paper-item').parent().child(i + 1)
            paper_name = item.ele('@class=item-info-title h-5 font-color-gray-mid').text
            print(paper_name)
            item.click()
            print(f'当前页{page_index}，当前卷{i + 1}，进入试卷...')
            analyse_paper(paper_name, page_index)
        paging = tab.ele('@class=paging')
        paging.child(-1).click()
        sleep(1)


def analyse_paper(paper_name, page_index):
    tab = chrom.latest_tab
    tab.set.NoneElement_value('')
    tab.listen.start()
    sleep(1)
    tab.ele('@class=submit-btn').click()
    tab.ele('@class=modal-action-btn btn-submit theme-box-shadow-inset-blue ng-tns-c3547082236-4').click()
    print('点击交卷...\n')

    # 确保所有题目都加载完毕
    sleep(1)
    tab.scroll.to_bottom()
    tab.scroll.to_top()
    tab.listen.wait_silent()

    ques_list = tab.eles('@class=content')
    print(f'总题数{len(ques_list)}:')

    # 标记每道题的题型
    ques_map = dict.fromkeys(range(1, len(ques_list)), None)
    idx = 0
    ques_types = tab.eles('@class=chapter-name ng-tns-c4236002343-6')
    for ques_type in ques_types:
        name = ques_type.texts(text_node_only=True)[0].strip()
        num = number_from_string(ques_type.child('@tag()=div').text.strip())
        print(f'{name} {num}道')
        for i in range(idx + 1, idx + num + 1):
            ques_map[i] = name.strip()
        idx = idx + num

    print(ques_map)
    print('\n')

    # 遍历题目
    for index, ques in enumerate(ques_list):
        print(f'{index + 1}. ')
        ques_type = ques_map[index + 1]
        if ques_type in SKIP_ITEMS:
            print(f'{ques_type}题，跳过\n')
            continue

        ques_info = QuesInfo(paper_name=paper_name, ques_type=ques_type)

        content_stems_all = []

        # 打印可能多题共用的材料
        material_stems_left = ques.parent('@class=right')
        if material_stems_left:
            material_stems = material_stems_left.prev().ele('@class=material-content').children('@tag()=p')
            for material_stem in material_stems:
                content_img = material_stem.ele(locator='@tag()=img', timeout=TIME_WAITTING).link
                content_text = material_stem.text
                print(f'{content_text}{content_img}')
                if content_img:
                    ques_info.content_img = content_img
                if content_text:
                    content_stems_all.append(content_text)

        # 打印题干
        ques_stems = ques.eles('@tag()=p')
        for ques_stem in ques_stems:
            content_text = ques_stem.text
            content_img = ques_stem.ele(locator='@tag()=img', timeout=TIME_WAITTING).link
            print(f"{ques_stem.text}{content_img}")
            if content_text:
                content_stems_all.append(content_text)
            if content_img:
                ques_info.content_img = content_img
        ques_info.content = '\n'.join(content_stems_all)

        # 打印选项
        choices = ques.next().eles('@tag()=li')
        for choice in choices:
            choice_name = choice.ele('@tag()=div').text.strip()
            choice_text = choice.ele('@tag()=p').text.strip()
            choice_img = choice.ele(locator='@tag()=img', timeout=TIME_WAITTING).link
            print(f"{choice_name}\t{choice_text}\t{choice_img}")
            if choice_name == 'A':
                ques_info.choice_a = choice_text
                if choice_img: ques_info.choice_a_img = choice_img
            elif choice_name == 'B':
                ques_info.choice_b = choice_text
                if choice_img: ques_info.choice_b_img = choice_img
            elif choice_name == 'C':
                ques_info.choice_c = choice_text
                if choice_img: ques_info.choice_c_img = choice_img
            elif choice_name == 'D':
                ques_info.choice_d = choice_text
                if choice_img: ques_info.choice_d_img = choice_img

        # 打印答案和正确率
        answer_box = ques.parent(2).next().child()
        answer = answer_box.child(1).child(1).text.strip()
        correct_percent = answer_box.child(3).child(1).text.strip()
        print(f'答案：{answer}\t 正确率：{correct_percent}')
        ques_info.answer = answer
        ques_info.rating = correct_percent
        print(ques_info)
        with DatabaseManager() as db:
            ques_table = QuesTable(db)
            ques_table.insert_ques(*astuple(ques_info))
        print('\n')

    tab.ele('@class=back-btn ng-star-inserted').click()
    print('返回首页...')
    sleep(1)
    tab.refresh()
    sleep(1)
    for _ in range(max(0, page_index - 1)):
        paging = tab.ele('@class=paging')
        paging.child(-1).click()
        sleep(1)


def number_from_string(s):
    match = re.search(r'\d+', s)
    return int(match.group()) if match else None


if __name__ == "__main__":
    # login()
    analyse_papers()
